/*
 * @Description: 
 * @Version: 2.0
 * @Autor: ruog__
 * @Date: 2025-05-09 19:55:32
 * @LastEditors: ruog__
 * @LastEditTime: 2025-06-11 17:05:38
 */
/*
 * @Description:
 * @Version: 2.0
 * @Autor: ruog__
 * @Date: 2025-05-09 19:55:32
 * @LastEditors: ruog__
 * @LastEditTime: 2025-06-11 17:04:38
 */
#define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE
#define _FILE_OFFSET_BITS 64
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <poll.h>
#include <signal.h>
#include <stdint.h>
#include <errno.h>
#include <stdlib.h>
#include <pthread.h>
#include <byteswap.h>
#include <string.h>
#include <ctype.h>
#include <termios.h>
#include <sys/mman.h>
#include "globle.h"

/* ltoh: little to host */
/* htol: little to host */
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define ltohl(x) (x)
#define ltohs(x) (x)
#define htoll(x) (x)
#define htols(x) (x)
#elif __BYTE_ORDER == __BIG_ENDIAN
#define ltohl(x) __bswap_32(x)
#define ltohs(x) __bswap_16(x)
#define htoll(x) __bswap_32(x)
#define htols(x) __bswap_16(x)
#endif

#define XDMA_CONFIG_MAP_SIZE (64 * 1024UL) // 64K
#define USR_CONFIG_MAP_SIZE (64 * 1024UL)  // 64K

static unsigned int c2h_user_be_ready_regs[] = {0x8000, 0x8000, 0xc002, 0xd002}; // 0xb002
static unsigned int c2h_block_id_regs[] = {0x18, 0x28, 0x38, 0x48};              // the regs stores the block id fpga maintians
static unsigned int h2c_user_be_ready_regs[] = {0x801c, 0xb012, 0xc012, 0xd012};

#define FPGA_DMA_WRITE_ENABLE(xdma_dev_ptr) write_bar(xdma_dev_ptr->usr_config_bar_map_address, FPGA_SIDE_DMA_WRITE_ENABLE_REG, FPGA_SIDE_DMA_WRITE_ENABLE)
#define ENABLE_FPGA_USR_IRQ(xdma_dev_ptr) write_bar(xdma_dev_ptr->usr_config_bar_map_address, FPGA_IRQ_CTL_REG, FPGA_IRQ_ENBALE)

#define sdma_down(xdma_dev_ptr) write_bar(xdma_dev_ptr->usr_config_bar_map_address, FPGA_SIDE_DMA_WRITE_ENABLE_REG, FPGA_sdma_RESET)
#define sdma_up(xdma_dev_ptr) write_bar(xdma_dev_ptr->usr_config_bar_map_address, FPGA_SIDE_DMA_WRITE_ENABLE_REG, 0)

#define WAIT_FOR_XDMA_DATA_READY_IRQ(data_informer_fd) is_data_ready(data_informer_fd)
#define C2H_CLR_XDMA_DATA_READY_IRQ(xdma_dev_ptr, channel_num) write_bar(xdma_dev_ptr->usr_config_bar_map_address, c2h_user_be_ready_regs[channel_num], CLEAR_IRQ_CMD)
#define C2H_USR_BE_READY(xdma_dev_ptr, channel_num) write_bar(xdma_dev_ptr->usr_config_bar_map_address, c2h_user_be_ready_regs[channel_num], USR_BE_READY_CMD)
#define H2C_CLR_XDMA_DATA_READY_IRQ(xdma_dev_ptr, channel_num) write_bar(xdma_dev_ptr->usr_config_bar_map_address, h2c_user_be_ready_regs[channel_num], CLEAR_IRQ_CMD)
#define H2C_USR_BE_READY(xdma_dev_ptr, channel_num) write_bar(xdma_dev_ptr->usr_config_bar_map_address, h2c_user_be_ready_regs[channel_num], USR_BE_READY_CMD)

#define DUMMY_READ_FOR_FPGA_USE(xdma_dev_ptr, channel_num) read_bar(xdma_dev_ptr->usr_config_bar_map_address, c2h_block_id_regs[channel_num])
#define ARRAY_SIZE(x) sizeof(x) / sizeof((x)[0])
#define DATA_C2H_TRANSFER_ON(xdma_dev_ptr) write_bar(xdma_dev_ptr->usr_config_bar_map_address, 0x8004, 2)
#define DATA_C2H_TRANSFER_OFF(xdma_dev_ptr) write_bar(xdma_dev_ptr->usr_config_bar_map_address, 0x8004, 0)
#define set_pcie_reggroup_reg8(xdma_dev_ptr) write_bar(xdma_dev_ptr->usr_config_bar_map_address, 0x8020, 0xabcdef)
#define reset_pcie_reggroup_reg8(xdma_dev_ptr) write_bar(xdma_dev_ptr->usr_config_bar_map_address, 0x8020, 0)

#define LOG_TAG "usr_xdma.c :"

static xdma_usr_dev *current_xdma_usr_dev = NULL;

extern unsigned int flag_file_end;
extern unsigned int flag_file_ok;
#define ddr_len 864

int init_get_data_informer(const char *path)
{
    int fd = -1;
    fd = open(path, O_RDWR);
    if (fd < 0)
    {
        LOGE(LOG_TAG "open %s failed,errno1 = %d\r\n", path, errno);
        return -errno;
    }
    return fd;
}

int shutdown_get_data_informer(int fd)
{
    if (fd > 0)
        close(fd);
}

int RESET_fpga()
{
    xdma_usr_dev *dev = current_xdma_usr_dev;

    DATA_C2H_TRANSFER_OFF(dev);
    sdma_down(dev);

    DATA_C2H_TRANSFER_ON(dev);
    sdma_up(dev);
}

int is_data_ready(int fd)
{
    int ret_val = -1;
    int irq_num = 0xffffffff;

    ret_val = read(fd, &irq_num, sizeof(irq_num));
    if (ret_val < 0)
    {
        LOGE(LOG_TAG "read failed,errno = %d\r\n", errno);
        return errno;
    }
    return irq_num;
}

void *get_ctr_bar_map_base(const char *path, int *fd, uint32_t map_size)
{
    int tmp_fd;
    char *map_base = NULL;
    uint32_t read_result, writeval;

    if ((tmp_fd = open(path, O_RDWR | O_SYNC)) == -1)
    {
        LOGE(LOG_TAG "open %s failed,errno = %d", path, errno);
        *fd = -1;
        return NULL;
    }
    LOGD(LOG_TAG "character device %s opened.\n", path);
    fflush(stdout);

    /* map one page */
    map_base = mmap(0, map_size, PROT_READ | PROT_WRITE, MAP_SHARED, tmp_fd, 0);
    if (map_base == (void *)-1)
    {
        LOGE(LOG_TAG "mmap failed,errno = %d\r\n", errno);
        close(tmp_fd);
        *fd = -1;
        return NULL;
    }
    *fd = tmp_fd;
    LOG("Memory map succeed!\r\n");
    LOGD(LOG_TAG "Memory mapped at address %p.\n", map_base);
    fflush(stdout);
    return map_base;
}

int release_bar_map(char *map_base, int fd, uint32_t map_size)
{
    RETURN_ERR(LOG_TAG, "munmap", munmap(map_base, map_size) < 0, 0);
    RETURN_ERR(LOG_TAG, "close release_bar_map", close(fd) < 0, 0);
    return 0;
}

int write_bar(char *map_base, off_t target, uint32_t value)
{
    uint32_t ret_val = 0;
    void *virt_addr = map_base + target;

    *((uint32_t *)virt_addr) = value;
    fflush(stdout);
    // LOGD("write_bar is called,address:0x%lx,value:0x%x--------------------------------\r\n",target,value);
    return ret_val;
}

uint32_t read_bar(char *map_base, off_t target)
{
    uint32_t ret_val = 0;
    void *virt_addr = map_base + target;

    ret_val = *((uint32_t *)virt_addr);
    fflush(stdout);
    // LOGD("read_bar is called,address:0x%lx,value:0x%x--------------------------------\r\n",target,ret_val);
    return ret_val;
}

static int get_c2h_channel_count(xdma_usr_dev *dev)
{
    int i = 0, count = 0;
    uint32_t value = 0xffffffff;
    for (i = 0; i < C2H_CHANNEL_MAX_NUM; i++)
    {
        value = read_bar(dev->xdma_config_bar_map_address, C2H_CHANNEL_IDENTIFIER_OFFSET + i * 0x0100);
        value = value >> 20;
        if (value == 0x1fc)
            count += 1;
    }
    return count;
}

static int get_h2c_channel_count(xdma_usr_dev *dev)
{
    int i = 0, count = 0;
    uint32_t value = 0xffffffff;
    for (i = 0; i < H2C_CHANNEL_MAX_NUM; i++)
    {
        value = read_bar(dev->xdma_config_bar_map_address, H2C_CHANNEL_IDENTIFIER_OFFSET + i * 0x0100);
        value = value >> 20;
        if (value == 0x1fc)
            count += 1;
    }
    return count;
}

static void *monitor_func(void *arg)
{
    int i = 0;
    static unsigned long long int c2h_data_before[C2H_CHANNEL_MAX_NUM];
    static unsigned long long int deliver_data_before[C2H_CHANNEL_MAX_NUM];
    static unsigned long long int rcv_data_before[H2C_CHANNEL_MAX_NUM];
    static unsigned long long int snd_data_before[H2C_CHANNEL_MAX_NUM];
    xdma_usr_dev *dev = (xdma_usr_dev *)arg;

    if (dev->monitor_period < 1)
        dev->monitor_period = 2;

    if (!dev->monitor_thread_running)
        dev->monitor_thread_running = 1;
    LOG("enter monitor thread,running = %d,period = %d\r\n", dev->monitor_thread_running, dev->monitor_period);
    for (i = 0; i < dev->c2h_channel_count; i++)
    {
        c2h_data_before[i] = 0;
        deliver_data_before[i] = 0;
    }
    for (i = 0; i < dev->h2c_channel_count; i++)
    {
        snd_data_before[i] = 0;
        rcv_data_before[i] = 0;
    }

    while (dev->monitor_thread_running)
    {
        sleep(dev->monitor_period);
        for (i = 0; i < dev->c2h_channel_count; i++)
        {
            dev->c2h_data_speed[i] = 1.0 * (dev->c2h_data_len[i] - c2h_data_before[i]) / dev->monitor_period / M_B;
            LOG("c2h[%d]            speed %.3f(MB/s),total c2h[%d]            data %luMB\r\n", i, dev->c2h_data_speed[i], i, dev->c2h_data_len[i] / M_B);
            c2h_data_before[i] = dev->c2h_data_len[i];

            dev->deliver_data_speed[i] = 1.0 * (dev->deliver_data_len[i] - deliver_data_before[i]) / dev->monitor_period / M_B;
            LOG("c2h[%d]-->user_app speed %.3f(MB/s),total c2h[%d]-->user_app data %luMB\r\n", i, dev->deliver_data_speed[i], i, dev->deliver_data_len[i] / M_B);
            deliver_data_before[i] = dev->deliver_data_len[i];
        }
        ///////////////////////////////////////////////////////////////////////////////////////////////
        for (i = 0; i < dev->h2c_channel_count; i++)
        {
            dev->rcv_data_speed[i] = 1.0 * (dev->rcv_data_len[i] - rcv_data_before[i]) / dev->monitor_period / M_B;
            LOG("user_app-->h2c[%d] speed %.3f(MB/s),total user_app-->h2c[%d] data %luMB\r\n", i, dev->rcv_data_speed[i], i, dev->rcv_data_len[i] / M_B);
            rcv_data_before[i] = dev->rcv_data_len[i];

            dev->h2c_data_speed[i] = 1.0 * (dev->h2c_data_len[i] - snd_data_before[i]) / dev->monitor_period / M_B;
            LOG("h2c[%d] speed %.3f(MB/s),total            h2c[%d] data %luMB\r\n", i, dev->h2c_data_speed[i], i, dev->h2c_data_len[i] / M_B);
            snd_data_before[i] = dev->h2c_data_len[i];
        }
        LOG("\r\n");
    }
}

static int open_or_create_file(const char *file_path, int clean_file)
{
    int fd = -1, ret_val = -1;
    fd = open(file_path, O_RDWR | O_CREAT | O_LARGEFILE);
    if (fd < 0)
    {
        LOGE(LOG_TAG "open failed for file:%s,errno = %d\r\n", file_path, errno);
        return -errno;
    }

    if (clean_file)
    {
        ret_val = ftruncate(fd, 0);
        if (fd < 0)
        {
            LOGE(LOG_TAG "ftruncate failed for file:%s,errno = %d\r\n", file_path, errno);
            return -errno;
        }
    }

    ret_val = chmod(file_path, 0766);
    if (ret_val < 0)
    {
        LOGE(LOG_TAG "chmod failed for file:%s,errno = %d\r\n", file_path, errno);
        return -errno;
    }

    return fd;
}

// #define STORE_SRC_DATA
static void *c2h_func(void *arg)
{
    char *tmp_position = NULL;
    unsigned char temp_buffer[1024] = {0};
    int block_id_user_side = 0, block_id_fpga_side = 0, read_cycle = 0;
    int ret_val = -1, i = 0, irq_id = 0;
    unsigned int block_type = 0;
    off_t abs_address = 0;
    int channel_num = *((int *)arg);
    static int count = 0;
    xdma_usr_dev *dev = current_xdma_usr_dev;

    unsigned char *p = NULL, *tmp = NULL;
    unsigned char file[30] = "/mnt/tx2/bmp";
    unsigned char string[10] = {0};
    FILE *fp;
    // unsigned int num = 1;
    // sprintf(string, "%d", num);
    // strcpy(file+12, string);
    // if((fp=fopen(file, "ab+")) == NULL){
    //     printf("file open failed\n");
    //     return -1;
    // }
    // p = (unsigned char*)malloc(ddr_len) ;
    // if(p==NULL) {
    //     printf("malloc failed\n");
    //     return -1;
    // }
    // tmp = p;

////////////////for debug
#ifdef STORE_SRC_DATA
    int srio_data_fd[5];
    char file_path[30];

    for (i = 0; i < ARRAY_SIZE(srio_data_fd); i++)
    {
        memset(file_path, '\0', sizeof(file_path));
        snprintf(file_path, sizeof(file_path), "rcv_srio_data_%d", i);
        srio_data_fd[i] = open_or_create_file(file_path, 1);
        if (srio_data_fd[i] < 0)
        {
            LOGE(LOG_TAG "chmopen_or_create_fileod failed for file:%s,errno = %d\r\n", file_path, errno);
        }
    }
#endif
    ////////////////for debug
    read_cycle = dev->user_side_ring_buffer_block_size / dev->fpga_side_ring_buffer_block_size;
    block_id_user_side = 0;
    LOG("enter c2h_func thread,running = %d,read_cycle = %d\r\n", dev->c2h_thread_running, read_cycle);
    while (dev->c2h_thread_running)
    {
        tmp_position = dev->c2h_block_buff_aligned[channel_num] + block_id_user_side * dev->user_side_ring_buffer_block_size;
        LOG("tmp_position= %p ,dev->c2h_block_buff_aligned[%d]= %x \r\n", tmp_position, channel_num, dev->c2h_block_buff_aligned[channel_num]);
        for (i = 0; i < read_cycle; i++)
        {
            C2H_USR_BE_READY(dev, channel_num);                                            // 打开中断
            irq_id = WAIT_FOR_XDMA_DATA_READY_IRQ(dev->c2h_data_informer_fd[channel_num]); // waiting for data_ready irq
            LOG("IRQ irq_id = %d  channel_num = %d\r\n", irq_id, channel_num);
            C2H_CLR_XDMA_DATA_READY_IRQ(dev, channel_num);                  // clear data_ready_irq
            block_id_fpga_side = DUMMY_READ_FOR_FPGA_USE(dev, channel_num); // dummy read for fpga,get the block id fpga maintians
            LOGD("block_id_fpga_side = %d\r\n", block_id_fpga_side);
            abs_address = (channel_num * dev->fpga_side_ring_buffer_block_num + block_id_fpga_side) * dev->fpga_side_ring_buffer_block_size;
            ERR_LOG(LOG_TAG, "lseek", lseek(dev->c2h_channel_fd[channel_num], abs_address, SEEK_SET) < 0);
#if 1
            //    ret_val = read(dev->c2h_channel_fd[channel_num], tmp_position + i * dev->fpga_side_ring_buffer_block_size, dev->fpga_side_ring_buffer_block_size);
            ret_val = read(dev->c2h_channel_fd[channel_num], temp_buffer, dev->fpga_side_ring_buffer_block_size);
            // ret_val = read(dev->c2h_channel_fd[channel_num], temp_buffer ,  900);

            // fwrite(tmp_position, ret_val, 1, fp);

            LOG("temp_buffer orin recv len = %d\r\n", ret_val);
            for (int k = 0; k < ret_val; k++)
            {
                if (k % 20 == 0)
                    printf("\r\n");
                printf("%02x ", temp_buffer[k]);
            }
            printf("\r\n");
#else
            ret_val = dev->fpga_side_ring_buffer_block_size;
#endif
            block_type = block_id_fpga_side / (dev->fpga_side_ring_buffer_block_num / dev->num_of_user_data_channel);
            dev->c2h_data_len[channel_num] += ret_val;
            ////////////////for debug
#ifdef STORE_SRC_DATA
            ret_val = write(srio_data_fd[block_type], tmp_position + i * dev->fpga_side_ring_buffer_block_size, ret_val);
            ERR_LOG(LOG_TAG, "write srio_data", ret_val < 0);
            usleep(100000);
#endif
            ////////////////for debug
        }
        if (dev->deliver_data == 1)
        {
            ret_val = snd_block_id(dev, block_id_user_side, block_type, channel_num);
            ERR_LOG(LOG_TAG, "snd_block_id", ret_val < 0);
        }
        block_id_user_side++;
        block_id_user_side = block_id_user_side % dev->user_side_ring_buffer_block_num;
        // usleep(500000);
    }
    ////////////////for debug
#ifdef STORE_SRC_DATA
    for (i = 0; i < ARRAY_SIZE(srio_data_fd); i++)
    {
        if (srio_data_fd[i] >= 0)
        {
            close(srio_data_fd[i]);
            srio_data_fd[i] = -1;
        }
    }
#endif
    ////////////////for debug
}

static void *h2c_func(void *arg)
{
    int block_id = 0, i = 0, ret_val = -1;
    unsigned int block_size = 0, block_number = 0, block_type = 0, total_rcv_pack = 0, abs_address = 0;
    char *tmp_position = NULL;
    unsigned char h2c_buf[1024] = {0};
    // unsigned char h2c_buf[99600] = {0};
    char str[4] = {0};
    int channel_num = *((int *)arg);
    xdma_usr_dev *dev = current_xdma_usr_dev;

    LOG("enter h2c_func thread,running = %d, channel_num=%d\r\n", dev->h2c_thread_running, channel_num);

#ifdef STORE_SRC_DATA
    int snd_blk_data_fd[5];
    char file_path[30];

    for (i = 0; i < ARRAY_SIZE(snd_blk_data_fd); i++)
    {
        memset(file_path, '\0', sizeof(file_path));
        snprintf(file_path, sizeof(file_path), "snd_blk_data_%d", i);
        snd_blk_data_fd[i] = open_or_create_file(file_path, 1);
        if (snd_blk_data_fd[i] < 0)
        {
            LOGE(LOG_TAG "chmopen_or_create_fileod failed for file:%s,errno = %d\r\n", file_path, errno);
        }
    }
#endif

    /*hepengkun add my for(;;)################################################################*/
    char *tmp_tmp_position = NULL;
    char temp_val = 4;
    unsigned int cnt = 0;
    // int sendNum = 0;
    while (dev->h2c_thread_running)
    {
        block_number = 0;
        while (dev->h2c_thread_running)
        {
            LOGD("waiting for input...\r\n");
#if 0
            if (fgets(str, sizeof(str), stdin))
            {
                size_t len = strlen(str);
                if (len > 0 && str[len - 1] == '\n') {
                    str[len - 1] = '\0'; // 替换换行符为字符串终止符
                }

                sendNum = atoi(str); // 直接转换整个字符串为数字
            }

            for(int fn = 0; fn<sendNum; fn++)
#else
            fgets(str, 4, stdin);
            if (str[0] == '1')
#endif
            {
                cnt = 0;
                //    abs_address = (block_number + dev->fpga_side_ring_buffer_block_num * (dev->c2h_channel_count + channel_num)) *  dev->fpga_side_ring_buffer_block_size;
                //    abs_address = (block_number + dev->fpga_side_ring_buffer_block_num * (2 + channel_num)) *  dev->fpga_side_ring_buffer_block_size;
                abs_address = 0x20000000; // 偏移512MB
#if 1
                tmp_position = dev->h2c_block_buff_aligned[channel_num] + block_number * (dev->fpga_side_ring_buffer_block_size);
                LOGD("tmp_position=%p,dev->h2c_block_buff_aligned[%d]=%x\r\n", tmp_position, channel_num, dev->h2c_block_buff_aligned[channel_num]);
                tmp_tmp_position = tmp_position;

                block_size = dev->fpga_side_ring_buffer_block_size ; // 100*864 + 132 // 100 * 864 + 100 * 132== 100 * 996 = 99600
#else
                block_size = 852;
#endif
                for (int j = 0; j < dev->fpga_side_ring_buffer_block_size ; j++)
                {
                    // *tmp_tmp_position++ = j ;
                    h2c_buf[j] = j;
                }

                h2c_buf[0] = 0x5C;
                h2c_buf[1] = 0xFB;
                h2c_buf[3] = temp_val++;
                h2c_buf[dev->fpga_side_ring_buffer_block_size - 2] = 0xFD;
                h2c_buf[dev->fpga_side_ring_buffer_block_size - 1] = 0xFE;

                H2C_USR_BE_READY(dev, channel_num);
                write_bar(dev->usr_config_bar_map_address, 0x20, abs_address + cnt * (852));
                write_bar(dev->usr_config_bar_map_address, 0x24, abs_address + cnt * (852));
                ERR_LOG(LOG_TAG, "lseek", lseek(dev->h2c_channel_fd[channel_num], abs_address + cnt * (852), SEEK_SET) < 0);
                //    ERR_LOG(LOG_TAG, "lseek", lseek(dev->h2c_channel_fd[channel_num],   cnt*996, SEEK_SET) < 0);
                write_bar(dev->usr_config_bar_map_address, 0x28, block_number << 16);

                ret_val = write(dev->h2c_channel_fd[channel_num], h2c_buf, block_size); // write data
                if (ret_val < 0)
                    LOGD("send failed !  %d\r\n", ret_val);
                else
                    LOGD("send OK !  %d\r\n", ret_val);

                block_size = block_size | 0xc0000000;
                write_bar(dev->usr_config_bar_map_address, 0x2c, block_size); // 写入   （发送数据块大小 | 0xc0000000）
                LOGD("block_size = 0x%x, block_number=%d, abs_address=%#x\r\n", block_size, block_number, abs_address + cnt * (852));
                //    WAIT_FOR_XDMA_DATA_READY_IRQ(dev->h2c_data_informer_fd[channel_num]); //waiting for data_ready irq
                //   LOGD("get data_informer_fd[%d] irq\r\n",channel_num);
                H2C_CLR_XDMA_DATA_READY_IRQ(dev, channel_num);
                write_bar(dev->usr_config_bar_map_address, 0x10, 0xffffffff); /// 和z7的0x43c00020直连
                dev->h2c_data_len[channel_num] += dev->h2c_msg_st[channel_num].block.block_size;

                block_number++;
                if (block_number % dev->fpga_side_ring_buffer_block_num == 0)
                    block_number = 0;

                // LOGD("time left 1s...\r\n");
                write_bar(dev->usr_config_bar_map_address, 0x8020, ++cnt); // 和z7的0x43c00038直连
                write_bar(dev->usr_config_bar_map_address, 0x801C, cnt);   ////和z7的0x43c00034直连     // 890项目功能做参考写入   0x1   清除h2c流程中fpga给cpu的数据发送完成中断
                write_bar(dev->usr_config_bar_map_address, 0x8024, cnt);   // 和z7的0x43c0003c直连
                LOGD("read 0x8020 is %#x\n", read_bar(dev->usr_config_bar_map_address, 0x8020));
                LOGD("read 0x8010 is %#x\n", read_bar(dev->usr_config_bar_map_address, 0x8010));
                if (cnt == 20000) // == PS
                    cnt = 0;

                sleep(1);
                // LOGD("time left 5s...\r\n");
                // sleep(5);
                memset(str, 0, 4);
            }
        }
    }
    /*#########################################################################################*/

    /*
        while (dev->h2c_thread_running)
        {
            block_id = rcv_block_id(dev,channel_num);  //阻塞模式
            if (block_id < 0)
            {
                LOGE(LOG_TAG"rcv_block_id failed,errno = %d\r\n", errno);
                continue;
            }

            block_type = dev->h2c_msg_st[channel_num].block.block_type;
            block_size = dev->h2c_msg_st[channel_num].block.block_size;
            block_number = dev->h2c_msg_st[channel_num].block.block_number;
            LOGD(LOG_TAG"snd big blk data,block_type = %d,block_size = %d,block_number = %d\r\n", dev->h2c_msg_st[channel_num].block.block_type, block_size, block_number);
    #ifdef STORE_SRC_DATA
            if (snd_blk_data_fd[block_type - ENMUM_RESERVE] >= 0)
            {
                ret_val = write(snd_blk_data_fd[block_type - ENMUM_SRIO_0], dev->h2c_block_buff_aligned[channel_num] + block_number * dev->fpga_side_ring_buffer_block_size, block_size);
                ERR_LOG(LOG_TAG, "write srio_data", ret_val < 0);
            }
            usleep(100000);
    #endif
    /////////////////////////////////////////////////////////////////////
            abs_address = (block_number + dev->fpga_side_ring_buffer_block_num * (dev->c2h_channel_count + channel_num)) *  dev->fpga_side_ring_buffer_block_size;
            tmp_position = dev->h2c_block_buff_aligned[channel_num] + block_number * dev->fpga_side_ring_buffer_block_size;

            H2C_USR_BE_READY(dev,channel_num);
            write_bar(dev->usr_config_bar_map_address, 0x20, abs_address);
            write_bar(dev->usr_config_bar_map_address, 0x24, abs_address);
            ERR_LOG(LOG_TAG, "lseek", lseek(dev->h2c_channel_fd[channel_num], abs_address, SEEK_SET) < 0);
            write_bar(dev->usr_config_bar_map_address, 0x28, block_number << 16);

            ret_val = write(dev->h2c_channel_fd[channel_num], tmp_position, block_size); //write data
            ERR_LOG(LOG_TAG, "write data", ret_val < 0);

            block_size = block_size | 0xc0000000;
            write_bar(dev->usr_config_bar_map_address, 0x2c, block_size);
            LOGD("block_size = 0x%x\r\n", block_size);
            WAIT_FOR_XDMA_DATA_READY_IRQ(dev->h2c_data_informer_fd[channel_num]); //waiting for data_ready irq
            LOGD("get data_informer_fd[%d] irq\r\n",channel_num);
            H2C_CLR_XDMA_DATA_READY_IRQ(dev,channel_num);
            write_bar(dev->usr_config_bar_map_address, 0x10, 0xffffffff);
            dev->h2c_data_len[channel_num] += dev->h2c_msg_st[channel_num].block.block_size;
            // if (dev->h2c_pos >= dev->fpga_side_ring_buffer_block_num)
            // {
            //     RETURN_ERR(LOG_TAG, "lseek", lseek(dev->h2c_channel_fd[0], 0, SEEK_SET) < 0, 1);
            //     dev->h2c_pos = 0;
            // }
        } */

#ifdef STORE_SRC_DATA
    for (i = 0; i < ARRAY_SIZE(snd_blk_data_fd); i++)
    {
        if (snd_blk_data_fd[i] >= 0)
        {
            close(snd_blk_data_fd[i]);
            snd_blk_data_fd[i] = -1;
        }
    }
#endif
}

int config_fpga_ring_buffer(xdma_usr_dev *dev)
{
    int i = 0;
    int val_1 = 0, val_2 = 0;
    uint32_t base_address = 0;

    if (!dev->usr_config_bar_map_address)
    {
        LOGE(LOG_TAG "config_fpga_ring_buffer,the para is null!\r\n");
        return -1;
    }

    printf("dev->fpga_side_ring_buffer_block_num=%d\r\n", dev->fpga_side_ring_buffer_block_num);

    base_address = FPGA_RING_BUFF_CONFIG_OFFSET;
    for (i = 0; i < dev->fpga_side_ring_buffer_block_num; i++)
    {
        write_bar(dev->usr_config_bar_map_address, base_address, dev->fpga_side_ring_buffer_block_size);
        base_address += 4;
        write_bar(dev->usr_config_bar_map_address, base_address, dev->fpga_side_ring_buffer_block_size * i);
        base_address += 4;
    }
    // 设置for循环之后 8 c 4 4 向寄存器写入块大小和数量 然后重置
    base_address = FPGA_CTR_REG + 0x8; // 块数量
    write_bar(dev->usr_config_bar_map_address, base_address, dev->fpga_side_ring_buffer_block_num / dev->num_of_user_data_channel);

    base_address = FPGA_CTR_REG + 0xc; // 大小
    write_bar(dev->usr_config_bar_map_address, base_address, dev->fpga_side_ring_buffer_block_size);

    base_address = FPGA_CTR_REG + 0x4;
    write_bar(dev->usr_config_bar_map_address, base_address, 1);
    usleep(10000);

    base_address = FPGA_CTR_REG + 0x4;
    write_bar(dev->usr_config_bar_map_address, base_address, 0);

    return 0;
}

static int c2h_channel_num[C2H_CHANNEL_MAX_NUM];
static int h2c_channel_num[H2C_CHANNEL_MAX_NUM];
int xdma_dev_init(xdma_usr_dev *dev)
{
    int fd_tmp = -1, i = 0;
    int ret_val = -1, tmp_direction = 0;
    char *tmp_ptr = NULL;
    uint32_t value = 0;
    int affinity_core_num = 0;

    current_xdma_usr_dev = dev;
    dev->h2c_thread_running = 0;
    dev->c2h_thread_running = 0;
    tmp_direction = dev->direction;
#define NAME_LEN 100
    for (i = 0; i < DATA_INFORMER_MAX_NUM; i++)
    {
        if (!dev->data_informer_path[i])
        {
            dev->data_informer_path[i] = (char *)malloc(NAME_LEN);
            CHECK_ERR(LOG_TAG, "malloc", !dev->data_informer_path[i], init_err_out);
            memset(dev->data_informer_path[i], '\0', NAME_LEN);
            snprintf(dev->data_informer_path[i], NAME_LEN, "%s%d", DATA_INFORMER_PATH_BASE, i);
            dev->data_informer_fd[i] = init_get_data_informer(dev->data_informer_path[i]);
            CHECK_ERR(LOG_TAG, "init_get_data_informer", dev->data_informer_fd[i] < 0, init_err_out);
        }
    }

    tmp_ptr = NULL;
    fd_tmp = -1;
    tmp_ptr = get_ctr_bar_map_base(USR_CONFIG_BAR_PATH, &fd_tmp, USR_CONFIG_MAP_SIZE);
    CHECK_ERR(LOG_TAG, "get_ctr_bar_map_base for USR_CONFIG_BAR", (!tmp_ptr || fd_tmp < 0), init_err_out);
    dev->usr_config_bar_map_address = tmp_ptr;
    dev->usr_config_bar_fd = fd_tmp;

    tmp_ptr = NULL;
    fd_tmp = -1;
    tmp_ptr = get_ctr_bar_map_base(XDMA_CONFIG_BAR_PATH, &fd_tmp, XDMA_CONFIG_MAP_SIZE);
    CHECK_ERR(LOG_TAG, "get_ctr_bar_map_base for XDMA_CONFIG_BAR", (!tmp_ptr || fd_tmp < 0), init_err_out);
    dev->xdma_config_bar_map_address = tmp_ptr;
    dev->xdma_config_bar_fd = fd_tmp;

    if (!dev->fpga_side_ring_buffer_block_num)
        dev->fpga_side_ring_buffer_block_num = 10;
    if (!dev->fpga_side_ring_buffer_block_size)
        dev->fpga_side_ring_buffer_block_size = 1 * K_B;

    write_bar(dev->usr_config_bar_map_address, 0x8020, 0); // 和z7的0x43c00038直连
    write_bar(dev->usr_config_bar_map_address, 0x801C, 0); ////和z7的0x43c00034直连
    write_bar(dev->usr_config_bar_map_address, 0x8024, 0); // 和z7的0x43c0003c直连
    write_bar(dev->usr_config_bar_map_address, 0x8010, 0); // 和z7的0x43c0003c直连

    config_fpga_ring_buffer(dev);
    ENABLE_FPGA_USR_IRQ(dev);   // 写DMA完成 0xC 写入4 bit2 = 1
    FPGA_DMA_WRITE_ENABLE(dev); // 写DMA使能 0x4 写入2 bit1 = 1
    DATA_C2H_TRANSFER_ON(dev);  // 0x8004 写入2        bit1 = 1

    value = read_bar(dev->usr_config_bar_map_address, FPGA_SIDE_DMA_WRITE_ENABLE_REG); // hepengkun
    write_bar(dev->usr_config_bar_map_address, FPGA_SIDE_DMA_WRITE_ENABLE_REG, 4 | value);
    value = read_bar(dev->usr_config_bar_map_address, FPGA_IRQ_CTL_REG);
    write_bar(dev->usr_config_bar_map_address, FPGA_IRQ_CTL_REG, 0x3 | value);

    if (!dev->user_side_ring_buffer_block_num)
        dev->user_side_ring_buffer_block_num = 10;
    if (!dev->user_side_ring_buffer_block_size)
        dev->user_side_ring_buffer_block_size = 1 * K_B;

    if (dev->direction & C2H_READ_DATA)
    {
        dev->direction = C2H_READ_DATA;
        dev->c2h_thread_running = 1;
        dev->c2h_channel_count = 0; // get_c2h_channel_count(dev);
        // printf("c2h_channel_count = %d\n", dev->c2h_channel_count);
        // for(i = 0;i < dev->c2h_channel_count;i++)
        i = 0;
        {
            dev->c2h_channel_path[i] = (char *)malloc(NAME_LEN);
            CHECK_ERR(LOG_TAG, "malloc", !dev->c2h_channel_path[i], init_err_out);
            memset(dev->c2h_channel_path[i], '\0', NAME_LEN);
            snprintf(dev->c2h_channel_path[i], NAME_LEN, "%s%d", C2H_CHANNEL_PATH_BASE, i);
            dev->c2h_channel_fd[i] = open(dev->c2h_channel_path[i], O_RDWR);
            printf("xdma0_c2h_%d = c2h_channel_fd[%d]=%d \r\n", i, i, dev->c2h_channel_fd[i]);
            CHECK_ERR(LOG_TAG, "open", dev->c2h_channel_fd[i] < 0, init_err_out);
            if (!dev->c2h_block_buff[i])
            {
                /// requier buffer
                // c2h_block_buff_aligned[0] = get_memory();
                tmp_ptr = generate_share_memory(dev, &(dev->c2h_share_memory_id[i]), i);
                CHECK_ERR(LOG_TAG, "generate_share_memory", !tmp_ptr, init_err_out);
                dev->c2h_block_buff[i] = tmp_ptr;
                dev->c2h_block_buff_aligned[i] = ADDRESS_ALIGN(dev->c2h_block_buff[i], BLOCK_ALIGN);
            }
            dev->c2h_msg_queue_id[i] = generate_msg_queue(dev, i);
            CHECK_ERR(LOG_TAG, "generate_msg_queue", dev->c2h_msg_queue_id[i] < 0, init_err_out);
            dev->c2h_msg_st[i].msg_type = C2H_MSG_TYPE;
            dev->c2h_data_informer_fd[i] = dev->data_informer_fd[i];

            c2h_channel_num[i] = i;
            //   printf("c2h_channel_num[%d] = %d\n", c2h_channel_num[i], i);
            ret_val = pthread_create_and_setaffinity(&(dev->c2h_thread[i]), NULL, c2h_func, &c2h_channel_num[i], affinity_core_num++);
            CHECK_ERR(LOG_TAG, "pthread_create_and_setaffinity for c2h_func", ret_val != 0, init_err_out);
        }
    }

    dev->direction = tmp_direction;
    if (dev->direction & H2C_WRITE_DATA)
    {
        dev->direction = H2C_WRITE_DATA;
        dev->h2c_thread_running = 1;
        dev->h2c_channel_count = 0; // get_h2c_channel_count(dev);
        // for(i = 0;i < dev->h2c_channel_count;i++)
        i = 0;
        {
            dev->h2c_channel_path[i] = (char *)malloc(NAME_LEN);
            CHECK_ERR(LOG_TAG, "malloc", !dev->h2c_channel_path[i], init_err_out);
            memset(dev->h2c_channel_path[i], '\0', NAME_LEN);
            snprintf(dev->h2c_channel_path[i], NAME_LEN, "%s%d", H2C_CHANNEL_PATH_BASE, i);
            dev->h2c_channel_fd[i] = open(dev->h2c_channel_path[i], O_RDWR);
            CHECK_ERR(LOG_TAG, "open", dev->h2c_channel_fd[i] < 0, init_err_out);
            if (!dev->h2c_block_buff[i])
            {
                /// requier buffer
                // h2c_block_buff_aligned[0] = get_memory();
                tmp_ptr = generate_share_memory(dev, &(dev->h2c_share_memory_id[i]), i);
                CHECK_ERR(LOG_TAG, "generate_share_memory", !tmp_ptr, init_err_out);
                dev->h2c_block_buff[i] = tmp_ptr;
                dev->h2c_block_buff_aligned[i] = ADDRESS_ALIGN(dev->h2c_block_buff[i], BLOCK_ALIGN);
            }

            dev->h2c_msg_queue_id[i] = generate_msg_queue(dev, i);
            CHECK_ERR(LOG_TAG, "generate_msg_queue", dev->h2c_msg_queue_id[i] < 0, init_err_out);
            dev->h2c_msg_st[i].msg_type = H2C_MSG_TYPE;
            //    dev->h2c_data_informer_fd[i] = dev->data_informer_fd[i + dev->c2h_channel_count]; //back
            dev->h2c_data_informer_fd[i] = dev->data_informer_fd[i + 2];

            h2c_channel_num[i] = i;
            ret_val = pthread_create_and_setaffinity(&(dev->h2c_thread[i]), NULL, h2c_func, &h2c_channel_num[i], affinity_core_num++);
            CHECK_ERR(LOG_TAG, "pthread_create_and_setaffinity for h2c_func", ret_val != 0, init_err_out);
        }
    }

    dev->direction = tmp_direction;
    dev->monitor_thread_running = 1;

    // ret_val = pthread_create_and_setaffinity(&(dev->monitor_thread), NULL, monitor_func, dev, affinity_core_num++);
    // CHECK_ERR(LOG_TAG,"pthread_create_and_setaffinity",ret_val != 0,init_err_out);
    // LOG("Number of enabled h2c channels = %d\r\n", dev->h2c_channel_count);
    // LOG("Number of enabled c2h channels = %d\r\n", dev->c2h_channel_count);
#undef NAME_LEN
    printf("test point 4 \r\n");
    return 0;
init_err_out:
    xdma_dev_deinit(dev);
    return -errno;
}

int xdma_dev_deinit(xdma_usr_dev *dev)
{
    int ret_val = -1, i = 0;

    DATA_C2H_TRANSFER_OFF(dev);
    if (dev->monitor_thread_running)
    {
        dev->monitor_thread_running = 0;
        if (dev->monitor_thread > 0)
        {
            // pthread_join(dev->monitor_thread, NULL);
            pthread_cancel(dev->monitor_thread);
            dev->monitor_thread = -1;
            dev->monitor_period = 0;
        }
    }

    if (dev->c2h_thread_running)
    {
        dev->c2h_thread_running = 0;
        for (i = 0; i < C2H_CHANNEL_MAX_NUM; i++)
        {
            if (dev->c2h_thread[i] > 0)
            {
                // pthread_join(dev->c2h_thread, NULL);
                pthread_cancel(dev->c2h_thread[i]);
                dev->c2h_thread[i] = -1;
            }
        }
    }

    if (dev->h2c_thread_running)
    {
        dev->h2c_thread_running = 0;
        for (i = 0; i < H2C_CHANNEL_MAX_NUM; i++)
        {
            if (dev->h2c_thread[i] > 0)
            {
                // pthread_join(dev->h2c_thread, NULL);
                pthread_cancel(dev->h2c_thread[i]);
                dev->h2c_thread[i] = -1;
            }
        }
    }

    for (i = 0; i < H2C_CHANNEL_MAX_NUM; i++)
    {
        if (dev->h2c_channel_path[i] && dev->h2c_channel_fd[i] > 0)
        {
            ERR_LOG(LOG_TAG, "close h2c_channel_fd", close(dev->h2c_channel_fd[i]) < 0);
            free(dev->h2c_channel_path[i]);
            dev->h2c_channel_path[i] = NULL;
            dev->h2c_channel_fd[i] = -1;
        }

        if (dev->h2c_block_buff[i])
        {
            ERR_LOG(LOG_TAG, "destroy_share_memory", destroy_share_memory(dev->h2c_block_buff[i], dev->h2c_share_memory_id[i]) < 0);
            dev->h2c_block_buff[i] = NULL;
            dev->h2c_block_buff_aligned[i] = NULL;
        }
    }
    dev->h2c_channel_count = 0;

    for (i = 0; i < C2H_CHANNEL_MAX_NUM; i++)
    {
        if (dev->c2h_channel_path[i] && dev->c2h_channel_fd[i] > 0)
        {
            ERR_LOG(LOG_TAG, "close c2h_channel_fd", close(dev->c2h_channel_fd[i]) < 0);
            free(dev->c2h_channel_path[i]);
            dev->c2h_channel_path[i] = NULL;
            dev->c2h_channel_fd[i] = -1;
        }

        if (dev->c2h_block_buff[i])
        {
            ERR_LOG(LOG_TAG, "destroy_share_memory", destroy_share_memory(dev->c2h_block_buff[i], dev->c2h_share_memory_id[i]) < 0);
            dev->c2h_block_buff[i] = NULL;
            dev->c2h_block_buff_aligned[i] = NULL;
        }
    }
    dev->c2h_channel_count = 0;

    for (i = 0; i < C2H_CHANNEL_MAX_NUM; i++)
    {
        if (dev->c2h_msg_queue_id[i] > 0)
        {
            ERR_LOG(LOG_TAG, "destroy_msg_queue for c2h", destroy_msg_queue(dev->c2h_msg_queue_id[i]) < 0);
            dev->c2h_msg_queue_id[i] = -1;
        }
    }

    for (i = 0; i < H2C_CHANNEL_MAX_NUM; i++)
    {
        if (dev->h2c_msg_queue_id[i] > 0)
        {
            ERR_LOG(LOG_TAG, "destroy_msg_queue for h2c", destroy_msg_queue(dev->h2c_msg_queue_id[i]) < 0);
            dev->h2c_msg_queue_id[i] = -1;
        }
    }

    for (i = 0; i < DATA_INFORMER_MAX_NUM; i++)
    {
        if (dev->data_informer_fd[i] > 0)
        {
            RETURN_ERR(LOG_TAG, "shutdown_get_data_informer", shutdown_get_data_informer(dev->data_informer_fd[i]) < 0, 0);
            dev->data_informer_fd[i] = -1;
        }

        if (dev->data_informer_path[i])
        {
            free(dev->data_informer_path[i]);
            dev->data_informer_path[i] = NULL;
        }
    }

    dev->fpga_side_ring_buffer_block_num = 0;
    dev->fpga_side_ring_buffer_block_size = 0;
    dev->user_side_ring_buffer_block_num = 0;
    dev->user_side_ring_buffer_block_size = 0;

    if (dev->usr_config_bar_map_address && dev->usr_config_bar_fd)
    {
        ret_val = release_bar_map(dev->usr_config_bar_map_address, dev->usr_config_bar_fd, USR_CONFIG_MAP_SIZE);
        RETURN_ERR(LOG_TAG, "release_bar_map", ret_val < 0, 0);
        dev->usr_config_bar_fd = -1;
        dev->usr_config_bar_map_address = NULL;
    }

    if (dev->xdma_config_bar_map_address && dev->xdma_config_bar_fd)
    {
        ret_val = release_bar_map(dev->xdma_config_bar_map_address, dev->xdma_config_bar_fd, XDMA_CONFIG_MAP_SIZE);
        RETURN_ERR(LOG_TAG, "release_bar_map", ret_val < 0, 0);
        dev->xdma_config_bar_fd = -1;
        dev->xdma_config_bar_map_address = NULL;
    }

    memset(dev, '\0', sizeof(xdma_usr_dev));
    current_xdma_usr_dev = NULL;

    return 0;
}

#ifdef DEBUG
int dump_xdma_dev(xdma_usr_dev *dev)
{
    int i = 0;

    for (i = 0; i < dev->c2h_channel_count; i++)
    {
        LOGD("c2h_channel_path[%d]                   : %s\r\n", i, dev->c2h_channel_path[i]);
        LOGD("c2h_channel_fd[%d]                     : %d\r\n", i, dev->c2h_channel_fd[i]);
        LOGD("c2h_share_memory_id[%d]                : %d\r\n", i, dev->c2h_share_memory_id[i]);
        LOGD("c2h_msg_queue_id[%d]                   : %d\r\n", i, dev->c2h_msg_queue_id[i]);
        LOGD("c2h_msg_st[%d].msg_type                : %ld\r\n", i, dev->c2h_msg_st[i].msg_type);
        LOGD("c2h_msg_st[%d].block.block_number      : %u\r\n", i, dev->c2h_msg_st[i].block.block_number);
        LOGD("c2h_thread[%d]                         : %d\r\n", i, (int)dev->c2h_thread[i]);
        LOGD("c2h_block_buff[%d]                     : %p\r\n", i, dev->c2h_block_buff[i]);
        LOGD("c2h_block_buff_aligned[%d]             : %p\r\n", i, dev->c2h_block_buff_aligned[i]);
    }
    LOGD("c2h_thread_running                     : %d\r\n", dev->c2h_thread_running);
    LOGD("c2h_channel_count                     : %d\r\n", dev->c2h_channel_count);

    for (i = 0; i < dev->h2c_channel_count; i++)
    {
        LOGD("h2c_channel_path[%d]                   : %s\r\n", i, dev->h2c_channel_path[i]);
        LOGD("h2c_channel_fd[%d]                     : %d\r\n", i, dev->h2c_channel_fd[i]);
        LOGD("h2c_share_memory_id[%d]                : %d\r\n", i, dev->h2c_share_memory_id[i]);
        LOGD("h2c_msg_queue_id[%d]                   : %d\r\n", i, dev->h2c_msg_queue_id[i]);
        LOGD("h2c_msg_st[%d].msg_type                : %ld\r\n", i, dev->h2c_msg_st[i].msg_type);
        LOGD("h2c_msg_st[%d].block.block_number      : %u\r\n", i, dev->h2c_msg_st[i].block.block_number);
        LOGD("h2c_thread[%d]                         : %d\r\n", i, (int)dev->h2c_thread[i]);
        LOGD("h2c_block_buff[%d]                     : %p\r\n", i, dev->h2c_block_buff[i]);
        LOGD("h2c_block_buff_aligned[%d]             : %p\r\n", i, dev->h2c_block_buff_aligned[i]);
    }
    LOGD("h2c_thread_running                     : %d\r\n", dev->h2c_thread_running);
    LOGD("h2c_channel_count                     : %d\r\n", dev->h2c_channel_count);

    for (i = 0; i < DATA_INFORMER_MAX_NUM; i++)
    {
        LOGD("data_informer_path[%d]                 : %s\r\n", i, dev->data_informer_path[i]);
        LOGD("data_informer_fd[%d]                   : %d\r\n", i, dev->data_informer_fd[i]);
    }

    LOGD("usr_config_bar_map_address            : %p\r\n", dev->usr_config_bar_map_address);
    LOGD("usr_config_bar_fd                     : %d\r\n", dev->usr_config_bar_fd);
    LOGD("xdma_config_bar_map_address           : %p\r\n", dev->xdma_config_bar_map_address);
    LOGD("xdma_config_bar_fd                    : %d\r\n", dev->xdma_config_bar_fd);

    LOGD("fpga_side_ring_buffer_block_num       : %d\r\n", dev->fpga_side_ring_buffer_block_num);
    LOGD("fpga_side_ring_buffer_block_size      : %uKB\r\n", (uint32_t)(dev->fpga_side_ring_buffer_block_size / K_B));
    LOGD("user_side_ring_buffer_block_num       : %d\r\n", dev->user_side_ring_buffer_block_num);
    LOGD("user_side_ring_buffer_block_size      : %uKB\r\n", (uint32_t)(dev->user_side_ring_buffer_block_size / K_B));

    LOGD("monitor_period                        : %d\r\n", dev->monitor_period);
    LOGD("monitor_thread_running                : %d\r\n", dev->monitor_thread_running);
    LOGD("num_of_user_data_channel              : %d\r\n", dev->num_of_user_data_channel);
    LOGD("monitor_thread                        : %d\r\n", (int)dev->monitor_thread);
    LOGD("direction                             : %d\r\n", dev->direction);
    LOGD("deliver_data                          : %d\r\n", dev->deliver_data);
    return 0;
}
#else
int dump_xdma_dev(xdma_usr_dev *dev)
{
    return 0;
}
#endif
